/*
 * Copyright (c) 2009, Hamish Morgan. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the University of Sussex nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package locusts.client;

import java.awt.RenderingHints;

/**
 *
 * @author Hamish Morgan
 */
public class RenderConfig {

    public transient static final int INTERPOLATION_NEAREST_NEIGHBOR = 0;
    public transient static final int INTERPOLATION_BILINEAR = 1;
    public transient static final int INTERPOLATION_BICUBIC = 2;
    //
    private transient static final boolean DEFAULT_QUALITY_ALPHA_INTERPOLATION =
            true;
    private transient static final boolean DEFAULT_ANTIALIASING = true;
    private transient static final boolean DEFAULT_TEXT_ANTIALIASING =
            true;
    private transient static final boolean DEFAULT_QUALITY_COLOR_RENDERING =
            true;
    private transient static final boolean DEFAULT_DITHERING = false;
    private transient static final boolean DEFAULT_FRACTIONAL_METRICS =
            true;
    private transient static final int DEFAULT_INTERPOLATION =
            INTERPOLATION_BICUBIC;
    private transient static final boolean DEFAULT_QUALITY_RENDERING =
            true;
    private transient static final boolean DEFAULT_PURE_STROKE_CONTROL =
            true;
    //
    private boolean qualityAlphaIterpolation;
    private boolean antialiasing;
    private boolean textAntialiasing;
    private boolean qualityColorRendering;
    private boolean dithering;
    private boolean fractionalMetrics;
    private int interpolation;
    private boolean qualityRendering;
    private boolean pureStrokeControl;
    //
    private transient RenderingHints renderingHints;

    public RenderConfig() {
        renderingHints = null;
        qualityAlphaIterpolation =
                DEFAULT_QUALITY_ALPHA_INTERPOLATION;
        antialiasing = DEFAULT_ANTIALIASING;
        textAntialiasing = DEFAULT_TEXT_ANTIALIASING;
        qualityColorRendering =
                DEFAULT_QUALITY_COLOR_RENDERING;
        dithering = DEFAULT_DITHERING;
        fractionalMetrics = DEFAULT_FRACTIONAL_METRICS;
        interpolation = DEFAULT_INTERPOLATION;
        qualityRendering = DEFAULT_QUALITY_RENDERING;
        pureStrokeControl = DEFAULT_PURE_STROKE_CONTROL;
    }

    public boolean isAntialiasing() {
        return antialiasing;
    }

    public void setAntialiasing(boolean antialiasing) {
        if (this.antialiasing != antialiasing) {
            this.antialiasing = antialiasing;
            renderingHints = null;
        }
    }

    public boolean isDithering() {
        return dithering;
    }

    public void setDithering(boolean dithering) {
        if (this.dithering != dithering) {
            this.dithering = dithering;
            renderingHints = null;
        }
    }

    public boolean isFractionalMetrics() {
        return fractionalMetrics;
    }

    public void setFractionalMetrics(boolean fractionalMetrics) {
        if (this.fractionalMetrics != fractionalMetrics) {
            this.fractionalMetrics = fractionalMetrics;
            renderingHints = null;
        }
    }

    public int getInterpolation() {
        return interpolation;
    }

    public void setInterpolation(int interpolation) {
        if (this.interpolation != interpolation) {
            this.interpolation = interpolation;
            renderingHints = null;
        }
    }

    public boolean isPureStrokeControl() {
        return pureStrokeControl;
    }

    public void setPureStrokeControl(boolean pureStrokeControl) {
        if (this.pureStrokeControl != pureStrokeControl) {
            this.pureStrokeControl = pureStrokeControl;
            renderingHints = null;
        }
    }

    public boolean isQualityAlphaIterpolation() {
        return qualityAlphaIterpolation;
    }

    public void setQualityAlphaIterpolation(
            boolean qualityAlphaIterpolation) {
        if (this.qualityAlphaIterpolation != qualityAlphaIterpolation) {
            this.qualityAlphaIterpolation = qualityAlphaIterpolation;
            renderingHints = null;
        }
    }

    public boolean isQualityColorRendering() {
        return qualityColorRendering;
    }

    public void setQualityColorRendering(boolean qualityColorRendering) {
        if (this.qualityColorRendering != qualityColorRendering) {
            this.qualityColorRendering = qualityColorRendering;
            renderingHints = null;
        }
    }

    public boolean isQualityRendering() {
        return qualityRendering;
    }

    public void setQualityRendering(boolean qualityRendering) {
        if (this.qualityRendering != qualityRendering) {
            this.qualityRendering = qualityRendering;
            renderingHints = null;
        }
    }

    public boolean isTextAntialiasing() {
        return textAntialiasing;
    }

    public void setTextAntialiasing(boolean textAntialiasing) {
        if (this.textAntialiasing != textAntialiasing) {
            this.textAntialiasing = textAntialiasing;
            renderingHints = null;
        }
    }

    public RenderingHints getRenderingHints() {

        if (renderingHints != null)
            return renderingHints;

        renderingHints = new RenderingHints(null);

        renderingHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION,
                isQualityAlphaIterpolation()
                ? RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY
                : RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);

        renderingHints.put(RenderingHints.KEY_ANTIALIASING,
                isAntialiasing()
                ? RenderingHints.VALUE_ANTIALIAS_ON
                : RenderingHints.VALUE_ANTIALIAS_OFF);

        renderingHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
                isTextAntialiasing()
                ? RenderingHints.VALUE_TEXT_ANTIALIAS_ON
                : RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);

        renderingHints.put(RenderingHints.KEY_COLOR_RENDERING,
                isQualityColorRendering()
                ? RenderingHints.VALUE_COLOR_RENDER_QUALITY
                : RenderingHints.VALUE_COLOR_RENDER_SPEED);

        renderingHints.put(RenderingHints.KEY_DITHERING,
                isDithering()
                ? RenderingHints.VALUE_DITHER_ENABLE
                : RenderingHints.VALUE_DITHER_DISABLE);

        renderingHints.put(RenderingHints.KEY_FRACTIONALMETRICS,
                isFractionalMetrics()
                ? RenderingHints.VALUE_FRACTIONALMETRICS_ON
                : RenderingHints.VALUE_FRACTIONALMETRICS_OFF);

        if (getInterpolation() == INTERPOLATION_NEAREST_NEIGHBOR) {
            renderingHints.put(RenderingHints.KEY_INTERPOLATION,
                    RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
        } else if (getInterpolation() == INTERPOLATION_BILINEAR) {
            renderingHints.put(RenderingHints.KEY_INTERPOLATION,
                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        } else { //getInterpolation() == INTERPOLATION_BICUBIC
            renderingHints.put(RenderingHints.KEY_INTERPOLATION,
                    RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        }

        renderingHints.put(RenderingHints.KEY_RENDERING,
                isQualityRendering()
                ? RenderingHints.VALUE_RENDER_QUALITY
                : RenderingHints.VALUE_RENDER_SPEED);

        renderingHints.put(RenderingHints.KEY_STROKE_CONTROL,
                isPureStrokeControl()
                ? RenderingHints.VALUE_STROKE_PURE
                : RenderingHints.VALUE_STROKE_NORMALIZE);

        return renderingHints;
    }
}
